package com.gzhu.knowledgeAdmin.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.code.kaptcha.Producer;
import com.gzhu.knowledgeAdmin.common.constant.RoleType;
import com.gzhu.knowledgeAdmin.common.exception.BusinessException;
import com.gzhu.knowledgeAdmin.common.param.UserInfoParam;
import com.gzhu.knowledgeAdmin.common.result.ErrorCode;
import com.gzhu.knowledgeAdmin.common.utils.MD5;
import com.gzhu.knowledgeAdmin.common.utils.UserInfoUtils;
import com.gzhu.knowledgeAdmin.common.vo.MenuVO;
import com.gzhu.knowledgeAdmin.common.vo.PageVo;
import com.gzhu.knowledgeAdmin.entity.User;
import com.gzhu.knowledgeAdmin.entity.UserRole;
import com.gzhu.knowledgeAdmin.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.awt.image.BufferedImage;
import java.util.*;
import java.util.concurrent.TimeUnit;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;


import com.gzhu.knowledgeAdmin.dao.XtyhDao;
import com.gzhu.knowledgeAdmin.entity.Xtyh;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;


@Service("xtyhService")
public class XtyhServiceImpl extends ServiceImpl<XtyhDao, Xtyh> implements XtyhService {

    @Autowired
    private PermissionService permissionService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    @Autowired
    private GsxxService gsxxService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private Producer producer;

    @Override
    public PageVo queryPage(Map<String, Object> params) {
        // 获取当前页和每页大小
        long pageNo = Long.parseLong((String) params.get("page"));
        long pageSize = Long.parseLong((String) params.get("limit"));
        String keyWord = (String) params.get("keyWord");

        Page<Xtyh> page = new Page<>(pageNo,pageSize);
        QueryWrapper<Xtyh> wrapper = new QueryWrapper<>();
        // 根据params里的查询参数添加条件查询
        if(!StringUtils.isEmpty(keyWord)){
            wrapper.like("F_YHM",keyWord);
        }

        // 当前是系统管理员获取还是公司管理员获取
        User user = UserInfoUtils.getCurrentUser();
        if(user.getYhlx()== RoleType.SYS_ADMIN){
            // 系统管理员，则剔除自身并不查询公司员工
            wrapper.ne("F_YHLX",RoleType.COMMON_USER);
            wrapper.ne("F_YHLX",RoleType.SYS_ADMIN).orderByAsc("F_GSID");
        }else {
            // 公司管理员只能查看本公司员工
            wrapper.eq("F_YHLX",RoleType.COMMON_USER).eq("F_GSID",user.getGsid());
        }

        baseMapper.selectPage(page,wrapper);

        // 查询每一个用户的角色、设置公司名称
        List<Xtyh> xtyhList = page.getRecords();
        for (Xtyh item : xtyhList) {
            item.setRylx(userRoleService.getRoleNameByUserId(item.getId()));
            item.setGsmc(gsxxService.getById(item.getGsid()).getGsmc());
        }

        return new PageVo(page);
    }

    @Override
    public Xtyh selectByUsername(String username) {

        return baseMapper.selectOne(new QueryWrapper<Xtyh>().eq("F_YHM", username));
    }

    @Override
    public Map<String, Object> getUserInfo(String username) {

        Map<String, Object> result = new HashMap<>();
        Xtyh user = selectByUsername(username);


        //根据用户id获取操作权限值
        List<String> permissionValueList = permissionService.selectPermissionValueByUserId(user.getId());
        stringRedisTemplate.opsForValue().set(username, JSON.toJSONString(permissionValueList));

        result.put("name", user.getYhm());
        result.put("avatar", "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
        result.put("permissionValueList", permissionValueList);
        result.put("yhlx",user.getYhlx());
        result.put("gsId",user.getGsid());
        return result;
    }

    @Override
    public void saveXtyh(Xtyh xtyh) {

        // 密码加密
        xtyh.setMm(MD5.encrypt(xtyh.getMm()));

        // 设置工号
        // TODO: 后期可以自定义命名规则
        String gh = UUID.randomUUID().toString().replaceAll("-", "").substring(0,20);
        xtyh.setGh(gh);

        // 如果不是系统管理员添加普通用户
        User user = UserInfoUtils.getCurrentUser();

        if(user.getYhlx()==RoleType.ADMIN){
            xtyh.setYhlx(RoleType.COMMON_USER); // 公司管理员添加的用户
            xtyh.setGsid(user.getGsid());// 本公司的用户
        }
        else {
            xtyh.setYhlx(RoleType.ADMIN);// 系统管理员只能添加公司管理员
        }


        // 添加记录
        baseMapper.insert(xtyh);


    }


    // 事务方法
    @Override
    @Transactional
    public void removeXtyhByIds(List<Integer> ids) {

        // 先删除用户角色表的相关数据
        userRoleService.deleteByUserIds(ids);

        // 再删除用户
        baseMapper.deleteBatchIds(ids);

    }

    @Override
    public void updateXtyh(Xtyh xtyh) {
        baseMapper.updateById(xtyh);
    }

    @Override
    public BufferedImage getCaptcha(String uuid) {


        if(StringUtils.isEmpty(uuid)){
            throw new RuntimeException("uuid不能为空");
        }
        //生成文字验证码
        String code = producer.createText();

        // 保存验证码,5分钟后过期
        stringRedisTemplate.opsForValue().set(uuid,code,5, TimeUnit.MINUTES);


        return producer.createImage(code);
    }

    @Override
    public boolean validate(String uuid, String code) {

        // 获取验证码
        String redisCode = stringRedisTemplate.opsForValue().get(uuid);
        if(StringUtils.isEmpty(redisCode)){
            return false;
        }

        //删除验证码
        stringRedisTemplate.delete(uuid);

        // 不区分大小写
        if(redisCode.equalsIgnoreCase(code)){
            return true;
        }

        return false;
    }

    @Override
    public void logout() {
        User curUser = UserInfoUtils.getCurrentUser();
        String userName = curUser.getUserName();


        List<String> keys = new ArrayList<>();
        keys.add(userName);
        keys.add("userInfo_"+userName);

        // 清除缓存权限信息、缓存用户信息
        stringRedisTemplate.delete(keys);

    }

    /**
     * 获取当前用户的菜单
     * @return
     */
    @Override
    public List<MenuVO> getCurUserMenu() {
        return permissionService.curUserPermissionVoList();
    }

    @Override
    public void resetPwd(List<Integer> ids) {

        // 默认重置密码为123456
        String encrypt = MD5.encrypt("123456");
        baseMapper.resetPwd(ids,encrypt);

    }
    private boolean isOldPwd(String oldPassword){
        // 校验旧密码
        Integer id = UserInfoUtils.getCurrentUser().getUserId();
        QueryWrapper<Xtyh> wrapper = new QueryWrapper<>();
        wrapper.eq("F_ID",id);
        wrapper.eq("F_MM",MD5.encrypt(oldPassword));

        Integer count = baseMapper.selectCount(wrapper);

        return count==1;
    }
    @Override
    public void updatePwd(UserInfoParam userInfoParam) {

        if(isOldPwd(userInfoParam.getOldPassword())==false){
            throw new BusinessException(ErrorCode.OLD_PWD_ERROR);
        }

        // 校验成功则修改
        Integer id = UserInfoUtils.getCurrentUser().getUserId();
        Xtyh xtyh = new Xtyh();
        xtyh.setId(id);
        xtyh.setMm(MD5.encrypt(userInfoParam.getNewPassword()));

        baseMapper.updateById(xtyh);
    }

    @Override
    public Boolean equlasOldPwd(String oldPassword) {
        return isOldPwd(oldPassword);
    }

    @Override
    public boolean nameIsExist(String name) {

        QueryWrapper<Xtyh> wrapper = new QueryWrapper<>();
        wrapper.eq("F_YHM",name);

        Integer count = baseMapper.selectCount(wrapper);

        return count>=1;
    }

    @Override
    public int hasGrantedRole(String userName) {

        // 超级管理员除外
        Xtyh xtyh = selectByUsername(userName);
        if(xtyh==null){
            return -2;
        }
        if(RoleType.SYS_ADMIN==xtyh.getYhlx()){
            return 1;
        }

        QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",xtyh.getId());
        return userRoleService.count(wrapper)>0?1:-1;

    }


}